Skip to content

fix(chat): prevent double send on mobile by removing redundant submit handlers#719

Merged
blackmammoth merged 1 commit into
siteboon:mainfrom
peterus:fix/double-send-mobile
May 30, 2026
Merged

fix(chat): prevent double send on mobile by removing redundant submit handlers#719
blackmammoth merged 1 commit into
siteboon:mainfrom
peterus:fix/double-send-mobile

Conversation

@peterus
Copy link
Copy Markdown
Contributor

@peterus peterus commented Apr 28, 2026

Summary

PromptInputSubmit is rendered as type=\"submit\" inside a <form> whose onSubmit already invokes handleSubmit. The component additionally wired onMouseDown and onTouchStart to call onSubmit directly, creating three submit paths.

On iOS Safari a single tap fires touchstart and a synthetic mousedown before React state propagates isLoading=true, so the disabled={!input.trim() || isLoading} guard does not catch the second invocation. Result: two user messages, two image-upload roundtrips per tap (visible as duplicate .tmp/images/<timestamp> folders).

This PR removes the redundant onMouseDown / onTouchStart handlers; the form's onSubmit is the single, browser-debounced submit path.

Test plan

  • Desktop click on the send button sends exactly once
  • Desktop Enter in the textarea sends exactly once
  • iOS Safari tap (with attached image) sends exactly once — single bubble, single .tmp/images/<ts> folder
  • Send-button disabled state still gates submission while isLoading

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Simplified event handling in the chat composer's submit control by removing redundant pointer/touch event interception, relying instead on standard form submission mechanics.

… handlers

PromptInputSubmit already has type="submit" via the parent form, so the
button's click triggers handleSubmit through the form's onSubmit path.
The added onMouseDown/onTouchStart handlers created two extra paths that
both invoked handleSubmit; on iOS Safari a single tap could fire both
touchstart and a synthetic mousedown before isLoading state propagated,
producing two messages and two image-upload roundtrips.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 28, 2026 16:01
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2cdf72a3-32a3-414e-9172-6c4767fb1c88

📥 Commits

Reviewing files that changed from the base of the PR and between f6200e3 and a809596.

📒 Files selected for processing (1)
  • src/components/chat/view/subcomponents/ChatComposer.tsx
💤 Files with no reviewable changes (1)
  • src/components/chat/view/subcomponents/ChatComposer.tsx

📝 Walkthrough

Walkthrough

The PromptInputSubmit component in the chat composer is simplified by removing pointer and touch event handlers (onMouseDown and onTouchStart). Form submission now relies entirely on standard form submission mechanics instead of manual event interception.

Changes

Cohort / File(s) Summary
Event Handler Simplification
src/components/chat/view/subcomponents/ChatComposer.tsx
Removed onMouseDown and onTouchStart handlers from PromptInputSubmit, eliminating manual event interception and default prevention; form submission now delegated to standard form mechanics.

Poem

🐰 A button once fretted and fussed all day,
Catching each touch in its complicated way,
But now it lets go, trusts the form to be true,
Simpler and cleaner—the rabbit's debut! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing redundant submit handlers to fix double-send issues on mobile platforms, which aligns with the file-level summary and PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes redundant direct-submit event handlers on the chat send button so message submission occurs through the form’s single onSubmit path, preventing double-send on mobile (notably iOS Safari).

Changes:

  • Removed onMouseDown and onTouchStart handlers from PromptInputSubmit usage to eliminate multiple submit paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@happytechca
Copy link
Copy Markdown

Thanks for this PR. I am having the same issue in Chrome on Android.

@wuc623123
Copy link
Copy Markdown

Confirming this is still reproducible on the latest packaged release.

Environment

  • Package: @cloudcli-ai/cloudcli@1.32.0 (downstream rebrand of this repo)
  • Browser: Firefox 151.0.1 on Linux (also reported on iOS Safari and Android Chrome above)
  • File checked: dist/assets/index-AaSE7-3t.js

Reproducer pattern that's still in the bundle

onTouchStart:ue=>{ue.preventDefault(),k(ue)}

k(ue) here is the submit handler. With the form already submitting on submit, the redundant onTouchStart invokes it a second time on touch devices that synthesize both events.

Patch verified working

Stripping that onTouchStart (or replacing with onTouchStart:void 0) eliminates the double-send on every touch device I could test. A simple in-place sed on the production bundle reproduces what this PR does at source level:

sed -i 's|onTouchStart:ue=>{ue.preventDefault(),k(ue)}|onTouchStart:void 0|' dist/assets/index-*.js

This has been running in production for me for several weeks with zero regressions on desktop click behaviour. Would be great to get this merged — the bug is mild on desktop but actively painful on mobile (every prompt sends twice, every image uploads twice). Happy to retest if you want a fresh confirmation after rebase.

@blackmammoth
Copy link
Copy Markdown
Collaborator

Hey @peterus, @happytechca, and @wuc623123 this has been merged. Also, if you’d like to join project discussion or community chat, we have a Discord here: link.

@blackmammoth blackmammoth merged commit dbc41dc into siteboon:main May 30, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants